/*
[思考]：如何让子类Woman也有唱歌的方法？
[解决]：
方式1：将唱歌的方法，定义到子类Woman中（代码冗余）
方式2：将唱歌的方法，定义到父类Person中（代码扩展性不好，唱歌的方法不能被其他类复用）
方式3：使用mixin扩展一个类，扩展类中定义唱歌的方法
[mixin] 表示一个没有构造函数的类，这个类的方法可以组合到其他类中实现代码复用
[mixin] 可以同时对某个类设置多个扩展类，也可以扩展属性
 */
void main() {
  // 创建男人对象
  Man man = Man('李雷', 13);
  print(man.name);
  man.eat();
  // 调用唱歌方法
  man.sing(man.name!);

  // 创建女人对象
  Woman woman = Woman('韩梅梅', 14);
  print(woman.name);
  woman.eat();
  // 调用跳舞方法
  woman.dance();
  // 调用唱歌方法
  woman.sing(woman.name!);
}

/// 人类
class Person {
  String? name;
  int? age;

  Person(this.name, this.age);

  void eat() {
    print('$name -- eat');
  }
}

/// 男人类
class Man extends Person with SingMixin {
  // 定义子类构造函数
  Man(super.name, super.age);
}

/// 女人类
class Woman extends Person with DanceMixin, SingMixin {
  // 定义子类构造函数
  Woman(super.name, super.age);
}

// 使用mixin扩展一个类，扩展类中定义唱歌的方法
mixin SingMixin {
// 唱歌的方法
  void sing(String name) {
    print('$name -- 爱唱歌');
  }
}
mixin DanceMixin {
  void dance() {
    print('爱跳舞');
  }
}
